package edu.whu.demo.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

// 定义一个切面类，用于对RestController的方法进行性能分析
@Aspect
@Component
public class ProfilingAspect {

    // 使用线程安全的Map存储方法名和对应的ApiMetric对象
    Map<String, ApiMetric> metrics = Collections.synchronizedMap(new HashMap<>());

    // 定义一个环绕通知，当方法被调用时执行
    @Around("@within(org.springframework.web.bind.annotation.RestController)")


    public Object doProfiling(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法签名
        String method = joinPoint.getSignature().toString();
        // 根据方法名从metrics中获取对应的ApiMetric对象，如果不存在则创建一个新的
        ApiMetric apiMetric= metrics.get(method);
        if (apiMetric == null) {
            apiMetric = new ApiMetric();

            metrics.put(method,apiMetric);
        }
        try {
            // 记录方法开始执行的时间
            long t1= Calendar.getInstance().getTimeInMillis();

            // 执行方法并获取结果
            Object result = joinPoint.proceed();


            // 记录方法执行结束的时间
            long t2= Calendar.getInstance().getTimeInMillis();
            // 计算方法执行时间并添加到ApiMetric对象中
            apiMetric.addTime((int)(t2-t1));

            return result;
        } catch (Throwable e) {
            // 如果方法执行过程中发生异常，将异常添加到ApiMetric对象中并抛出
            apiMetric.addException(e);
            throw e;
        }
    }

    // 提供一个方法，用于获取所有的ApiMetric对象
    public Map<String, ApiMetric> getMetrics() {
        return metrics;
    }
}

